﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using SearchScreen.SearchScreenModule.Model;
using System.Xml.Serialization;
using System.IO;

namespace SearchScreen.SearchScreenModule.ViewModel
{

    class DomainTypesViewModel: INotifyPropertyChanged
    {
        #region Data
        
        bool? _isChecked = false;
        DomainTypesViewModel _parent;
        
        #endregion // Data

        #region LoadTreeView

        public DomainTypesViewModel(string name)
        {
            this.Name = name;
            this.Children = new List<DomainTypesViewModel>();
        }

        public void Initialize()
        {

            foreach (DomainTypesViewModel child in this.Children)
            {
                child._parent = this;
                child.Initialize();
            }
            this.HierarchicalName = SetHierarchicalName(this);
            //this.currentTreeItem = SetCurrentTreeItem(this);
        }

        // Mode Tree View
        private TreeViewItem SetCurrentTreeItem(DomainTypesViewModel current)
        {
            TreeViewItem item = new TreeViewItem();
            item.Header = current.Name;

            TreeViewItem parentTree = item;

            while (current._parent != null)
            {
                current = current._parent;
                item = parentTree;

                parentTree = new TreeViewItem();
                parentTree.Header = current.Name;
                parentTree.Items.Add(item);
            }

            return parentTree;
        }

        private string SetHierarchicalName(DomainTypesViewModel current)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(this.Name);

            while (current._parent != null)
            {
                sb.Append("|");
                current = current._parent;
                sb.Append(current.Name);
            }

            return sb.ToString();
        }

        #endregion // LoadTreeView

        #region Properties

        public List<DomainTypesViewModel> Children { get; private set; }

        public string Name { get; private set; }

        public string HierarchicalName { get; private set; }

        public TreeViewItem currentTreeItem { get; private set; }

        #region IsChecked

        /// <summary>
        /// Gets/sets the state of the associated UI toggle (ex. CheckBox).
        /// The return value is calculated based on the check state of all
        /// child DomainTypesViewModels.  Setting this property to true or false
        /// will set all children to the same check state, and setting it 
        /// to any value will cause the parent to verify its check state.
        /// </summary>
        public bool? IsChecked
        {
            get { return _isChecked; }
            set { this.SetIsChecked(value, true, true); }
        }

        public event EventHandler OnIsCheckedChanged;

        void SetIsChecked(bool? value, bool updateChildren, bool updateParent)
        {
            if (value == _isChecked)
                return;

            _isChecked = value;

            if (updateChildren && _isChecked.HasValue)
                this.Children.ForEach(c => c.SetIsChecked(_isChecked, true, false));

            if (updateParent && _parent != null)
                _parent.VerifyCheckState();

            this.OnPropertyChanged("IsChecked");
            if (this.OnIsCheckedChanged != null)
            {
                this.OnIsCheckedChanged(this, new EventArgs());
            }
        }

        void VerifyCheckState()
        {
            bool? state = null;
            for (int i = 0; i < this.Children.Count; ++i)
            {
                bool? current = this.Children[i].IsChecked;
                if (i == 0)
                {
                    state = current;
                }
                else if (state != current)
                {
                    state = null;
                    break;
                }
            }
            this.SetIsChecked(state, false, true);
        }

        #endregion // IsChecked

        #endregion // Properties

        #region INotifyPropertyChanged Members

        void OnPropertyChanged(string prop)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(prop));

        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
